/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://gitee.com/newgolo/embedme.git
 * Copyright 2014~2020 @ ShenZhen ,China
*******************************************************************************/
#ifdef OS_CYGWIN
#else
#include "Tracer.h"
#include "KeyInput.h"

namespace libemb{
KeyInput::KeyInput():
m_fdInput(-1)
{
}

KeyInput::~KeyInput()
{
}

bool KeyInput::open(const string& devName)
{
    if (m_fdInput>0)
    {
        return true;
    }
    m_fdInput = ::open(devName.c_str(),O_RDWR);
    if (m_fdInput<0)
    {
        return false;
    }
    m_mainThread.start(this);
    return true;
}

bool KeyInput::close()
{
    if (m_fdInput>0)
    {
        ::close(m_fdInput);
        m_fdInput = -1;
    }
    m_mainThread.cancel();
    m_listenerList.clear();
    return true;
}
/**
 *  @brief  注册按键事件监听者
 *  @param  keyListener 事件监听者
 *  @return void
 *  @note   注册后,事件监听者需要实现handleKey来处理按键事件
 */
void KeyInput::registerKeyListener(KeyListener* keyListener)
{
    AutoLock lock(&m_listenerLock);
    m_listenerList.push_back(keyListener);
}

/**
 *  @brief  取消注册按键事件监听者
 *  @param  keyListener 事件监听者
 *  @return void
 *  @note   none
 */
void KeyInput::unregisterKeyListener(KeyListener* keyListener)
{
    AutoLock lock(&m_listenerLock);
    m_listenerList.remove(keyListener);   
}

void KeyInput::run(Thread& thread)
{   
    while(1)
    {
        struct input_event event;
        if((m_fdInput>0) && (read(m_fdInput,&event,sizeof(event))))
        {
            if(event.type != EV_KEY)
		    {
		        continue;
            }
           	if (event.value == 1)
            {
                list<KeyListener*>::iterator iter;
                AutoLock lock(&m_listenerLock);
                for(iter=m_listenerList.begin();iter!=m_listenerList.end();iter++)
                {
                    (*iter)->handleKey(event.code,event.value);
                }
			}
		}
    }
}
}
#endif
